package com.yztc.orangeentertainment.widget.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;

import com.yztc.orangeentertainment.R;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

/**
 * Created by My on 2016/10/5.
 */
public class GifView extends View {

    private Movie mMovie;
    /**
     * 动画开始时间
     */
    private long mMovieStart;
    private boolean mPaused = false;
    /**
     * 当前帧动画时间
     */
    private int mCurrentAnimationTime;
    /**
     * 自定义的三个属性
     */
    private boolean decode_STREAM;
    private int src_ID;
    private int default_time;

    public GifView(Context context) {
        super(context);
        init(context, null);
    }

    public GifView(Context context, AttributeSet set) {
        super(context, set);
        init(context, set);
    }

    private void init(Context context, AttributeSet set) {

        TypedArray a = context.obtainStyledAttributes(set,
                R.styleable.gifCommon);
        src_ID = a.getResourceId(R.styleable.gifCommon_gif_src, -1);
        decode_STREAM = a.getBoolean(R.styleable.gifCommon_decode_stream, true);
        default_time = a.getInteger(
                R.styleable.gifCommon_default_animation_time, 1000);
        a.recycle();

        setFocusable(true);
        java.io.InputStream is;
        is = context.getResources().openRawResource(src_ID);

        if (decode_STREAM) {
            mMovie = Movie.decodeStream(is);    // 根据文件流创建Movier绘制对象
        } else {
            byte[] array = streamToBytes(is);
            mMovie = Movie.decodeByteArray(array, 0, array.length);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mMovie != null) {
            if (!mPaused) {
                // 更新帧时间
                updateAnimationTime();
                drawMovieFrame(canvas);
                invalidate();
            } else {
                // 暂停时，不更新帧时间，则只画当前帧
                drawMovieFrame(canvas);
            }
        }
    }

    private void updateAnimationTime() {
        long now = android.os.SystemClock.uptimeMillis();
        // 如果第一帧，记录起始时间
        if (mMovieStart == 0) {
            mMovieStart = now;
        }
        // 取出动画的时长
        int dur = mMovie.duration();
        if (dur == 0) {
            dur = default_time;
        }
        // 算出需要显示第几帧
        mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
    }

    private void drawMovieFrame(Canvas canvas) {
        // 设置要显示的帧，绘制即可
        mMovie.setTime(mCurrentAnimationTime);
        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        mMovie.draw(canvas, 0, 0);
        canvas.restore();
    }

    /**
     * 设置暂停
     *
     * @param paused
     */
    public void setPaused(boolean paused) {
        this.mPaused = paused;
        if (!paused) {
            /**
             * 更新动画起点时间
             */
            mMovieStart = android.os.SystemClock.uptimeMillis()
                    - mCurrentAnimationTime;
        }
        invalidate();
    }

    /**
     * 判断gif图是否停止了
     *
     * @return
     */
    public boolean isPaused() {
        return this.mPaused;
    }

    /**
     * 重写此方法，使自定义View支持wrap_content
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width;
        int height;
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {

            int desired = (int) (getPaddingLeft() + mMovie.width() + getPaddingRight());
            width = Math.min(desired, widthSize);
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            int desired = (int) (getPaddingTop() + mMovie.height() + getPaddingBottom());
            height = Math.min(desired, heightSize);
        }

        setMeasuredDimension(width, height);
    }

    /**
     * 将流转化为字节数组
     *
     * @param is
     * @return
     */
    private static byte[] streamToBytes(InputStream is) {
        ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
        byte[] buffer = new byte[1024];
        int len;
        try {
            while ((len = is.read(buffer)) >= 0) {
                os.write(buffer, 0, len);
            }
        } catch (java.io.IOException e) {
        }
        return os.toByteArray();
    }

}